home *** CD-ROM | disk | FTP | other *** search
/ STraTOS 1997 April & May / STraTOS 1 - 1997 April & May.iso / CD01 / GNU_KIT / DISK8.ZIP / src / makest / file.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-08-08  |  11.2 KB  |  467 lines

  1. /* Copyright (C) 1988, 1989, 1990 Free Software Foundation, Inc.
  2. This file is part of GNU Make.
  3.  
  4. GNU Make is free software; you can redistribute it and/or modify
  5. it under the terms of the GNU General Public License as published by
  6. the Free Software Foundation; either version 1, or (at your option)
  7. any later version.
  8.  
  9. GNU Make is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12. GNU General Public License for more details.
  13.  
  14. You should have received a copy of the GNU General Public License
  15. along with GNU Make; see the file COPYING.  If not, write to
  16. the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
  17.  
  18. #include "make.h"
  19. #include "commands.h"
  20. #include "dep.h"
  21. #include "file.h"
  22. #include "variable.h"
  23. #include <errno.h>
  24.  
  25.  
  26. extern int errno;
  27.  
  28.  
  29. /* Hash table of files the makefile knows how to make.  */
  30.  
  31. #ifndef    FILE_BUCKETS
  32. #define FILE_BUCKETS    1007
  33. #endif
  34. static struct file *files[FILE_BUCKETS];
  35.  
  36. /* Number of files with the `intermediate' flag set.  */
  37.  
  38. unsigned int num_intermediates = 0;
  39.  
  40.  
  41. /* Access the hash table of all file records.
  42.    lookup_file  given a name, return the struct file * for that name,
  43.            or nil if there is none.
  44.    enter_file   similar, but create one if there is none.  */
  45.  
  46. struct file *
  47. lookup_file (name)
  48.      char *name;
  49. {
  50.   register struct file *f;
  51.   register char *n;
  52.   register unsigned int hashval;
  53.  
  54.   if (*name == '\0')
  55.     abort ();
  56.  
  57.   while (name[0] == '.' && name[1] == '/' && name[2] != '\0')
  58.     name += 2;
  59.  
  60.   hashval = 0;
  61.   for (n = name; *n != '\0'; ++n)
  62.     HASH (hashval, *n);
  63.   hashval %= FILE_BUCKETS;
  64.  
  65.   for (f = files[hashval]; f != 0; f = f->next)
  66.     if (streq (f->name, name))
  67.       return f;
  68.   return 0;
  69. }
  70.  
  71. struct file *
  72. enter_file (name)
  73.      char *name;
  74. {
  75.   register struct file *f, *new;
  76.   register char *n;
  77.   register unsigned int hashval;
  78.  
  79.   if (*name == '\0')
  80.     abort ();
  81.  
  82.   hashval = 0;
  83.   for (n = name; *n != '\0'; ++n)
  84.     HASH (hashval, *n);
  85.   hashval %= FILE_BUCKETS;
  86.  
  87.   for (f = files[hashval]; f != 0; f = f->next)
  88.     if (streq (f->name, name))
  89.       break;
  90.  
  91.   if (f != 0 && !f->double_colon)
  92.     return f;
  93.  
  94.   new = (struct file *) xmalloc (sizeof (struct file));
  95.   bzero ((char *) new, sizeof (struct file));
  96.   new->name = name;
  97.   new->update_status = -1;
  98.  
  99.   if (f == 0)
  100.     {
  101.       /* This is a completely new file.  */
  102.       new->next = files[hashval];
  103.       files[hashval] = new;
  104.     }
  105.   else
  106.     {
  107.       /* There is already a double-colon entry for this file.  */
  108.       while (f->prev != 0)
  109.     f = f->prev;
  110.       f->prev = new;
  111.     }
  112.  
  113.   return new;
  114. }
  115.  
  116. /* Rename FILE to NAME.  This is not as simple as resetting
  117.    the `name' member, since it must be put in a new hash bucket,
  118.    and possibly merged with an existing file called NAME.  */
  119.  
  120. void
  121. rename_file (file, name)
  122.      register struct file *file;
  123.      char *name;
  124. {
  125.   char *oldname = file->name;
  126.   register unsigned int oldhash, newhash;
  127.   register char *n;
  128.   register struct file *f;
  129.   struct file *oldfile;
  130.  
  131.   /* Find the hash values of the old and new names.  */
  132.  
  133.   oldhash = 0;
  134.   for (n = oldname; *n != '\0'; ++n)
  135.     HASH (oldhash, *n);
  136.   oldhash %= FILE_BUCKETS;
  137.  
  138.   newhash = 0;
  139.   for (n = name; *n != '\0'; ++n)
  140.     HASH (newhash, *n);
  141.   newhash %= FILE_BUCKETS;
  142.  
  143.   /* Look for an existing file under the new name.  */
  144.  
  145.   for (oldfile = files[newhash]; oldfile != 0; oldfile = oldfile->next)
  146.     if (streq (oldfile->name, name))
  147.       break;
  148.  
  149.   if (newhash != oldhash || oldfile != 0)
  150.     {
  151.       /* Remove FILE from its hash bucket.  */
  152.  
  153.       struct file *lastf = 0;
  154.  
  155.       for (f = files[oldhash]; f != file; f = f->next)
  156.     lastf = f;
  157.  
  158.       if (lastf == 0)
  159.     files[oldhash] = f->next;
  160.       else
  161.     lastf->next = f->next;
  162.     }
  163.  
  164.   /* Give FILE its new name.  */
  165.  
  166.   for (f = file; f != 0; f = f->prev)
  167.     f->name = name;
  168.  
  169.   if (oldfile == 0)
  170.     {
  171.       /* There is no existing file with the new name.  */
  172.  
  173.       if (newhash != oldhash)
  174.     {
  175.       /* Put FILE in its new hash bucket.  */
  176.       file->next = files[newhash];
  177.       files[newhash] = file;
  178.     }
  179.     }
  180.   else
  181.     {
  182.       /* There is an existing file with the new name.
  183.      We must merge FILE into the existing file.  */
  184.  
  185.       register struct dep *d;
  186.  
  187.       if (file->cmds != 0)
  188.     {
  189.       if (oldfile->cmds == 0)
  190.         oldfile->cmds = file->cmds;
  191.       else if (file->cmds != oldfile->cmds)
  192.         {
  193.           /* We have two sets of commands.  We will go with the
  194.          one given in the rule explicitly mentioning this name,
  195.          but give a message to let the user know what's going on.  */
  196.           error ("%s:%u: Commands were specified for file `%s' at %s:%u,",
  197.              file->cmds->filename, file->cmds->lineno,
  198.              oldname, oldfile->cmds->filename, oldfile->cmds->lineno);
  199.           error ("%s:%u: but `%s' is now considered the same file \
  200. as `%s'.",
  201.              file->cmds->filename, file->cmds->lineno,
  202.              oldname, name);
  203.           error ("%s:%u: Commands for `%s' will be ignored \
  204. in favor of those for `%s'.",
  205.              file->cmds->filename, file->cmds->lineno,
  206.              name, oldname);
  207.         }
  208.     }
  209.  
  210.       /* Merge the dependencies of the two files.  */
  211.  
  212.       d = oldfile->deps;
  213.       if (d == 0)
  214.     oldfile->deps = file->deps;
  215.       else
  216.     {
  217.       while (d->next != 0)
  218.         d = d->next;
  219.       d->next = file->deps;
  220.       uniquize_deps (oldfile->deps);
  221.     }
  222.  
  223.       merge_variable_set_lists (&oldfile->variables, file->variables);
  224.  
  225.       if (oldfile->double_colon && !file->double_colon)
  226.     fatal ("can't rename single-colon `%s' to double-colon `%s'",
  227.            oldname, name);
  228.       if (!oldfile->double_colon && file->double_colon)
  229.     fatal ("can't rename double-colon `%s' to single-colon `%s'",
  230.            oldname, name);
  231.  
  232. #define MERGE(field) oldfile->field |= file->field
  233.       MERGE (precious);
  234.       MERGE (tried_implicit);
  235.       MERGE (updating);
  236.       MERGE (updated);
  237.       MERGE (is_target);
  238.       MERGE (cmd_target);
  239.       MERGE (phony);
  240. #undef MERGE
  241.  
  242.       file->renamed = oldfile;
  243.     }
  244. }
  245.  
  246. /* Remove all nonprecious intermediate files.
  247.    If SIG is nonzero, this was caused by a fatal signal,
  248.    meaning that a different message will be printed, and
  249.    the message will go to stderr rather than stdout.  */
  250.  
  251. void
  252. remove_intermediates (sig)
  253.      int sig;
  254. {
  255.   register int i;
  256.   register struct file *f;
  257.   char doneany;
  258.   
  259.   if (!sig && just_print_flag)
  260.     return;
  261.  
  262.   doneany = 0;
  263.   for (i = 0; i < FILE_BUCKETS; ++i)
  264.     for (f = files[i]; f != 0; f = f->next)
  265.       if (f->intermediate && (f->dontcare || !f->precious))
  266.     {
  267.       int status;
  268.       if (just_print_flag)
  269.         status = 0;
  270.       else
  271.         {
  272.           status = unlink (f->name);
  273.           if (status < 0 && errno == ENOENT)
  274.         continue;
  275.         }
  276.       if (!f->dontcare)
  277.         {
  278.           if (sig)
  279.         error ("*** Deleting file `%s'", f->name);
  280.           else if (!silent_flag && !just_print_flag)
  281.         {
  282.           if (!doneany)
  283.             {
  284.               fputs ("rm ", stdout);
  285.               doneany = 1;
  286.             }
  287.           putchar (' ');
  288.           fputs (f->name, stdout);
  289.           fflush (stdout);
  290.         }
  291.           if (status < 0)
  292.         perror_with_name ("unlink: ", f->name);
  293.         }
  294.     }
  295.  
  296.   if (doneany && !sig)
  297.     {
  298.       putchar ('\n');
  299.       fflush (stdout);
  300.     }
  301. }
  302.  
  303. /* For each dependency of each file, make the `struct dep' point
  304.    at the appropriate `struct file' (which may have to be created).
  305.  
  306.    Also mark the files depended on by .PRECIOUS and .PHONY.  */
  307.  
  308. void
  309. snap_deps ()
  310. {
  311.   register struct file *f, *f2;
  312.   register struct dep *d;
  313.   register int i;
  314.  
  315.   /* Enter each dependency name as a file.  */
  316.   for (i = 0; i < FILE_BUCKETS; ++i)
  317.     for (f = files[i]; f != 0; f = f->next)
  318.       for (f2 = f; f2 != 0; f2 = f2->prev)
  319.     for (d = f2->deps; d != 0; d = d->next)
  320.       if (d->name != 0)
  321.         {
  322.           d->file = lookup_file (d->name);
  323.           if (d->file == 0)
  324.         d->file = enter_file (d->name);
  325.           else
  326.         free (d->name);
  327.           d->name = 0;
  328.         }
  329.   
  330.   for (f = lookup_file (".PRECIOUS"); f != 0; f = f->prev)
  331.     for (d = f->deps; d != 0; d = d->next)
  332.       for (f2 = d->file; f2 != 0; f2 = f2->prev)
  333.     f2->precious = 1;
  334.  
  335.   for (f = lookup_file (".PHONY"); f != 0; f = f->prev)
  336.     for (d = f->deps; d != 0; d = d->next)
  337.       for (f2 = d->file; f2 != 0; f2 = f2->prev)
  338.     {
  339.       /* Mark this file as phony and nonexistent.  */
  340.       f2->phony = 1;
  341.       f2->last_mtime = (time_t) -1;
  342.     }
  343. }
  344.  
  345. /* Print the data base of files.  */
  346.  
  347. void
  348. print_file_data_base ()
  349. {
  350.   register unsigned int i, nfiles, per_bucket;
  351.   register struct file *file;
  352.   register struct dep *d;
  353.  
  354.   puts ("\n# Files");
  355.  
  356.   per_bucket = nfiles = 0;
  357.   for (i = 0; i < FILE_BUCKETS; ++i)
  358.     {
  359.       register unsigned int this_bucket = 0;
  360.  
  361.       for (file = files[i]; file != 0; file = file->next)
  362.     {
  363.       register struct file *f;
  364.  
  365.       ++this_bucket;
  366.  
  367.       for (f = file; f != 0; f = f->prev)
  368.         {
  369.           putchar ('\n');
  370.           if (!f->is_target)
  371.         puts ("# Not a target:");
  372.           printf ("%s:%s", f->name, f->double_colon ? ":" : "");
  373.           
  374.           for (d = f->deps; d != 0; d = d->next)
  375.         printf (" %s", dep_name (d));
  376.           putchar ('\n');
  377.           
  378.           if (f->precious)
  379.         puts ("#  Precious file (dependency of .PRECIOUS).");
  380.           if (f->phony)
  381.         puts ("#  Phony target (dependency of .PHONY).");
  382.           if (f->cmd_target)
  383.         puts ("#  Command-line target.");
  384.           if (f->dontcare)
  385.         puts ("#  A default or MAKEFILES makefile.");
  386.           printf ("#  Implicit rule search has%s been done.\n",
  387.               f->tried_implicit ? "" : " not");
  388.           if (f->stem != 0)
  389.         printf ("#  Implicit/static pattern stem: `%s'\n", f->stem);
  390.           if (f->intermediate)
  391.         puts ("#  File is an intermediate dependency.");
  392.           if (f->also_make != 0)
  393.         {
  394.           register unsigned int i;
  395.           fputs ("#  Also makes:", stdout);
  396.           for (i = 0; f->also_make[i] != 0; ++i)
  397.             printf (" %s", f->also_make[i]);
  398.           putchar ('\n');
  399.         }
  400.           if (f->last_mtime == (time_t) 0)
  401.         puts ("#  Modification time never checked.");
  402.           else if (f->last_mtime == (time_t) -1)
  403.         puts ("#  File does not exist.");
  404.           else
  405.         printf ("#  Last modified %.24s (%ld)\n",
  406.             ctime (&f->last_mtime), (long int) f->last_mtime);
  407.           printf ("#  File has%s been updated.\n",
  408.               f->updated ? "" : " not");
  409.           switch (f->command_state)
  410.         {
  411.         case cs_running:
  412.           puts ("#  Commands currently running (?!).");
  413.           break;
  414.         case cs_deps_running:
  415.           puts ("#  Dependencies currently being made (?!).");
  416.           break;
  417.         case cs_not_started:
  418.         case cs_finished:
  419.           switch (f->update_status)
  420.             {
  421.             case -1:
  422.               break;
  423.             case 0:
  424.               puts ("#  Successfully updated.");
  425.               break;
  426.             case 1:
  427.               puts ("#  Failed to be updated.");
  428.               break;
  429.             default:
  430.               puts ("#  Invalid value in `update_status' member!");
  431.               fflush (stdout);
  432.               fflush (stderr);
  433.               abort ();
  434.             }
  435.           break;
  436.         default:
  437.           puts ("#  Invalid value in `command_state' member!");
  438.           fflush (stdout);
  439.           fflush (stderr);
  440.           abort ();
  441.         }
  442.  
  443.           if (f->variables != 0)
  444.         print_file_variables (file);
  445.  
  446.           if (f->cmds != 0)
  447.         print_commands (f->cmds);
  448.         }
  449.     }
  450.  
  451.       nfiles += this_bucket;
  452.       if (this_bucket > per_bucket)
  453.     per_bucket = this_bucket;
  454.     }
  455.  
  456.   if (nfiles == 0)
  457.     puts ("\n# No files.");
  458.   else
  459.     {
  460.       printf ("\n# %u files in %u hash buckets.\n", nfiles, FILE_BUCKETS);
  461. #ifndef    NO_FLOAT
  462.       printf ("# average %.1f files per bucket, max %u files in one bucket.\n",
  463.           ((double) FILE_BUCKETS) / ((double) nfiles) * 100.0, per_bucket);
  464. #endif
  465.     }
  466. }
  467.